if (!window.Facebook) Facebook = {
	Class: {}
};

Facebook.ColumnWidth = 600;
Facebook.MarginLeft = 54;
Facebook.Ids = {};

Facebook.Class.Base = new Class({
	Extends: Baja.Class.Widget,
	
	pv_options: {
		postId: '166141936778079',
		groupId: '126207900788383',
		//groupId: '167652659956854',
		fbUrlHttp: 'http://graph.facebook.com',
		fbUrlHttps: 'https://graph.facebook.com',
		fbAuthUrl: Baja.AppPath + 'facebook/php/fb.auth.php',
		fbFeedUrl: Baja.AppPath + 'facebook/php/fb.postnews.php',
		fbLikeUrl: Baja.AppPath + 'facebook/php/fb.post.php',
		profileId: ''
	},
	
	loadItem: function (options) {
		var my = this, op = my.pv_options;
		var ajaxOptions = jQuery.extend(true, {
			type: 'GET',
			dataType: 'jsonp',
			async: true,
			data: {
				access_token: Baja.Session('FbAccessToken') || 'xxx'
			},
			error: function () {
				Baja.RemoveSesson('FbAccessToken');
				Baja.RemoveSesson('FbAccessFresh');
			}
		
		}, options);
		ajaxOptions.success = function (fbo) {
			Baja.Trace('Came back from FB');
			my.onErrorRevalidate(fbo);
			if (fbo) {
				if (options.success) options.success.call(my, fbo);
			}
		};
		if (options['public']) delete ajaxOptions.data.access_token;
		if (options.loadUser) my.loadUser(function (user) {
			my.$meName.html(user.name);
			my.$mePicture.attr('src', 'http://graph.facebook.com/' + user.id + '/picture');

		});
		jQuery.ajax(ajaxOptions);
	},
	
	indexId: function ($el, id) {
		Facebook.Ids[id] = $el;
		$el.attr('id', id);
	},
	
	classId: function (id) {
		return 'ID__' + id;
	},

	fillPost: function (fbo) {
		var my = this, op = my.pv_options;
		var nodes = fbo.comments.data;
		my.$description.html(fbo.message);
		my.$listCount.html('(' + nodes.length + ' comments)');
		for (var i=0,l=nodes.length; i<l; i++) {
			new Facebook.Class.Comment({
				$container: my.$widget,
				fbNode: nodes[i]
			});
		}
	},

	fillGroup: function (fbo) {
		var my = this;
		my.$topic.html(fbo.name);
		my.$description.html(fbo.description);
	},
	
	fillFeed: function (fbo) {
		var my = this, nodes = fbo.data;
		my.$listCount.html('(' + nodes.length + ' comments)');
		for (var i=0,l=nodes.length; i<l; i++) {
			nodes[i].commentWidget = new Facebook.Class.Item({
				container: my.$feed,
				fbNode: nodes[i]
			});
		}
	},

	onErrorRevalidate: function (fbo) {
		var my = this, op = my.pv_options;
		if (fbo && fbo.error) {
			if (fbo.error.type != 'OAuthException') {
				Baja.Session('FbLastError', fbo.error);
				alert(fbo.error.message);
				throw 'FBError';
			}
			if (Baja.Session('FbAccessFresh') && (new Date()).getTime() - Baja.Session('FbAccessFresh') < 20000) {
				my.error('Facebook validation failure');
				throw 'FBError';
			}
			Baja.Session('FbAccessFresh', (new Date()).getTime());
			my.error(fbo.error.message);
			Baja.CollectLastUserAction(my.pv_className);
			location.href = location.protocol + '//' + location.host + '/' + op.fbAuthUrl;
			my.trace('url=/'+op.fbAuthUrl);
			throw 'FBDone';
		}
		Baja.RemoveSession('FbAccessFresh');
	},
	
	captureAccessToken: function () {
		if (/access_token=/.test(location.search)) {
			var atk = location.getValue('access_token');
			Baja.Session('FbAccessToken', atk);
			Baja.RemoveSession('FbAccessFresh');
			location.href = location.rawUrl();
			throw 'PageReloading';
		}
	},
	
	loadGroup: function (id, fn) {
		var my = this, op = my.pv_options;
		my.captureAccessToken();
		Baja.Trace('Sending for it on FB');
		my.loadItem({
			url: op.fbUrlHttp + '/' + id,
			data: {},
			loadUser: true,
			'public': true,
			success: function (fbo) {
				my.fillGroup(fbo);
				my.loadItem({
					url: op.fbUrlHttp + '/' + id + '/feed',
					'public': true,
					success: function (fbo) {
						my.fillFeed(fbo);
					}
				})
				if (fn) fn.call(my, fbo);
			}
		});
	},
	
	loadPost: function (id, fn) {
		var my = this, op = my.pv_options;
		my.captureAccessToken();
		Baja.Trace('Sending for it on FB');
		my.loadItem({
			url: op.fbUrlHttps + '/' + id,
			loadUser: true,
			data: {
				limit: 25,
				offset: 0
			},
			success: function (fbo) {
				my.loadNext(fbo, fn);
			}
		})
	},
	
	loadNext: function (fbo1, fn) {
		var my = this, op = my.pv_options;
		jQuery.ajax({
			url: (op.fbUrlHttps + '/' + op.postId + '/comments'),
			type: 'GET',
			dataType: 'jsonp',
			data: {
				limit: op.limit,
				access_token: Baja.Session('FbAccessToken')
			},
			success: function (fbo) {
				if (fbo === false || (fbo && fbo.error)) {
					alert(fbo && fbo.error.message || 'request returned false');
					if (fn) fn.call(my, fbo1);
					return;
				}
				if (fbo && fbo.data) {
					//fbo1.comments.data = fbo1.comments.data.concat(fbo.data);
					fbo1.comments.data = fbo.data;
				}
				if (fn) fn.call(my, fbo1);
				return;
				setTimeout(function () {
					my.loadNext(fbo1, fn);
				}, 1);
			},
			error: function () {
				my.error('FB TRANSPORT ERROR');
			}
		})
	},
	
	loadUser: function (fn) {
		var my = this, op = my.pv_options;
		Facebook.User = Baja.Session('FbUserObject');
		jQuery.ajax({
			url: (op.fbUrlHttps + '/me'),
			type: 'GET',
			dataType: 'jsonp',
			data: {
				access_token: Baja.Session('FbAccessToken')
			},
			success: function (fbo) {
				my.onErrorRevalidate(fbo);
				if (fbo) {
					Facebook.User = fbo;
					Baja.Session('FbUserObject', fbo);
				}
				if (fn) fn.call(my, fbo);
			},
			error: function () {
				my.error('FB TRANSPORT ERROR');
			}
		})
	},
	
	loadLikes: function (id, fn) {
		var my = this, op = my.pv_options;
		my.loadItem({
			url: (op.fbUrlHttps + '/' + id + '/likes'),
			success: fn
		})
	},
	
	reStatus: function (id) {
		var my = this, op = my.pv_options;
		my.loadItem({
			url: (op.fbUrlHttps + '/' + id),
			success: function (fbo) {
				new Facebook.Class.Status({
					$container: jQuery('.status', jQuery('.'+my.classId(id))),
					fbNode: fbo
				});
			}
		});
	},
	
	likeIt: function (id, ic) {
		var my = this, op = my.pv_options;
		var data = {
			itemId: id,
			command: 'likes',
			accessToken: Baja.Session('FbAccessToken')
		};
		if (!ic) data.method = 'delete';
		if (Facebook.User) jQuery.ajax({
			url: '/' + op.fbLikeUrl,
			type: 'POST',
			dataType: 'jsonp',
			data: data,
			success: function (fbo) {
				if (fbo === false || (fbo && fbo.error)) {
					alert(fbo && fbo.error.message || 'request returned false');
					return;
				}
				my.loadLikes(id, function (fbo) {
					new Facebook.Class.Likes({
						$container: jQuery('.likes', jQuery('.'+my.classId(id))),
						fbNode: fbo
					})
				});
				my.reStatus(id);
			},
			error: function () {
				my.error('FB TRANSPORT ERROR');
			}
		})
		else alert('user not known yet');
	},
	
	postNewItem: function (options) {
		var my = this, op = my.pv_options;
		jQuery.ajax({
			url: '/' + op.fbFeedUrl,
			type: 'POST',
			dataType: 'jsonp',
			data: jQuery.extend ({
				profileId: op.groupId,
				accessToken: Baja.Session('FbAccessToken')
			}, options),
			success: function (fbo) {
				if (fbo === false || (fbo && fbo.error)) {
					alert(fbo && fbo.error.message || 'request returned false');
					return;
				}
				location.reload(true);
			},
			error: function () {
				my.error('FB TRANSPORT ERROR');
			}
		});
	},
	
	removeItem: function (id) {
		var my = this, op = my.pv_options;
		var data = {
			itemId: id,
			method: 'delete',
			accessToken: Baja.Session('FbAccessToken')
		};
		jQuery.ajax({
			url: '/' + op.fbLikeUrl,
			type: 'POST',
			dataType: 'jsonp',
			data: data,
			success: function (fbo) {
				if (fbo === false || (fbo && fbo.error)) {
					alert(fbo && fbo.error.message || 'request returned false');
					return;
				}
				location.reload(true);
			},
			error: function () {
				my.error('FB TRANSPORT ERROR');
			}
		})
	},
	
	postToNewsFeed: function (options) {
		var my = this, op = my.pv_options;
		if (Facebook.User) jQuery.ajax({
			url: '/' + op.fbFeedUrl,
			type: 'POST',
			dataType: 'jsonp',
			data: jQuery.extend ({
				profileId: Facebook.User.id,
				accessToken: Baja.Session('FbAccessToken')
			}, options),
			success: function (fbo) {
				if (fbo === false || (fbo && fbo.error)) {
					alert(fbo && fbo.error.message || 'request returned false');
					return;
				}
			},
			error: function () {
				my.error('FB TRANSPORT ERROR');
			}
		})
		else alert('user not known yet');
	}
});

Facebook.Class.Post = new Class({
	Extends: Facebook.Class.Base,
	pv_className: 'Facebook.Class.Post',
	
	pv_options: {
		limit: 1000,
		elements: {
			wija: false,
			$widget: {
				css: {
					position: 'relative',
					top: -30,
					left: 0,
					right: 0,
					margin: 0,
					padding: 0,
					textAlign: 'center'
				}
			},
			$topic: {
				tag: '<h1/>',
				html: 'Facebook Column',
				css: {
					position: 'relative',
					top: 20,
					marginTop: 0
				}
			},
			$description: {
				tag: '<div/>',
				id: 'description#',
				css: {
					width: Facebook.ColumnWidth,
					margin: 'auto',
					fontSize: '18px',
					fontFamily: 'Georgia'
				}
			},
			$listCount: {
				tag: '<div/>',
				css: {
					display: 'none',
					fontSize: '11px',
					fontFamily: 'Georgia'
				}
			},
			$addItemBox: {
				tag: '<div/>',
				//wija: true,
				css: {
					position: 'relative',
					width: Facebook.ColumnWidth,
					margin: '8px auto 38px auto'
				}
			},
			$addItem: {
				tag: '<textarea/>',
				parent: '$addItemBox',
				css: {
					position: 'relative',
					width: '100%',
					height: 35,
					backgroundColor: '#FFC'
				}
			},
			$addItemButton: {
				tag: '<button/>',
				id: '@self',
				parent: '$addItemBox',
				html: 'Share',
				css: {
					position: 'relative',
					top: 5,
					'float': 'right'
				},
				click: function (e,my) {
					my.postNewItem({
						message: my.$addItem.Val()
					});
				}
			},
			$feed: {
				tag: '<div class="feed"/>',
				wija: true,
				css: {
					width: Facebook.ColumnWidth,
					margin: '0px auto',
					padding: '0 5px 50px 5px',
					textAlign: 'left',
					//backgroundColor: '#FFC'
					backgroundColor: 'transparent'
				}
			},
			$me: {
				tag: '<div/>',
				id: '@self',
				css: {
					position: 'absolute',
					top: -80,
					left: 40,
					fontSize: '10pt'
				}
			},
			$mePicture: {
				tag: '<img/>',
				parent: '$me',
				css: {
					position: 'absolute',
					top: 30,
					left: 30,
					width: 48,
					height: 48,
					paddingRight: 5
				}
			},
			$meName: {
				tag: '<div/>',
				parent: '$me',
				css: {
					position: 'absolute',
					width: 300,
					top: 33,
					left: 30+48+5,
					textAlign: 'left'
				}
			},
			/*
			$postToNewsFeedButton: {
				tag: '<button/>',
				html: 'post "hello there from tmt" to <i>my</i> news feed',
				id: '@self',
				css: {
					position: 'absolute',
					top: 10,
					right: 10
				},
				click: function (e,my) {
					my.postToNewsFeed({
						message: 'hello there from tmt'
					});
				}
			},
			$loadUserButton: {
				tag: '<button/>',
				html: 'load my fb profile',
				id: '@self',
				css: {
					position: 'absolute',
					top: 30,
					right: 10
				},
				click: function (e,my) {
					my.loadUser(function (data) {
						new Facebook.Class.User({
							after: my.$listCount,
							data: data
						});
					});
				}
			},
			*/
			onload: function (my) {
				Baja.FireLastUserAction(my.pv_className);
			}
		}
	},
	
	initialize: function (options) {
		var my = this, op = my.pv_options;
		jQuery.extend(op, options);
		
		my.parent();
		my.createWidget(function () {
			my.$widget.appendTo('#PAGE');
			my.loadGroup(op.groupId);
		});
	//		my.loadPost(op.postId, function (fbo) {
	//			my.fillPost(fbo);
	//		});
	}
	
});

Facebook.Class.Item = new Class({
	
	Extends: Facebook.Class.Base,
	
	pv_options: {
		container: null,
		fbNode: null,
		
		elements: {
			wija: false,
			$widget: {
				css: {
					position: 'relative',
					width: '100%',
					margin: '0',
					padding: '8px 0',
					textAlign: 'left',
					clear: 'both'
				}
			},
			$item: {
				tag: '<div class="item"/>',
				wija: true,
				css: {
					position: 'relative',
					margin: '0 0 0 0',
					padding: '8px 0 8px 0',
					borderTop: '1px solid #CCC',
					fontSize: '12px',
					fontFamily: 'Calibri,Georgia, Helvetica, Arial'
				},
				build: function (my, op) {
					this.addClass(my.classId(op.fbNode.id));
				//my.indexId(this, op.fbNode.id);
				}
			},
			$avatar: {
				tag: '<div class="avatar"/>',
				parent: '$item',
				css: {
					width: 48,
					height: 48,
					'float':'left'
				}
			},
			$avatarImg: {
				tag: '<img class="avatarImg"/>',
				parent: '$avatar',
				css: {
					width: '100%',
					height: '100%'
				}
			},
			$message: {
				tag: '<div class="message"/>',
				parent: '$item',
				css: {
					marginLeft: Facebook.MarginLeft
				}
			},
			$status: {
				tag: '<div class="status"/>',
				wija: true,
				parent: '$item',
				css: {
					marginLeft: Facebook.MarginLeft,
					fontSize: '9pt'
				}
			},
			$likes: {
				tag: '<div class="likes"/>',
				wija: true,
				parent: '$item',
				css: {
					marginLeft: Facebook.MarginLeft,
					fontSize: '9pt',
					backgroundColor: '#CCA'
				}
			},
			$comments: {
				tag: '<div class="comments"/>',
				wija: true,
				parent: '$item',
				css: {
					marginLeft: Facebook.MarginLeft
				}
			}
		}
	},

	initialize: function (options) {
		var my = this, op = my.pv_options;
		jQuery.extend(op, options);
		if (!Facebook.People) Facebook.People = {};
		my.parent();
		my.createWidget(function () {
			var src = 'http://graph.facebook.com/' + op.fbNode.from.id + '/picture';
			my.$message.html('<div><b><a href="">' + op.fbNode.from.name + '</a></b> ' + op.fbNode.message + '</div>');
			if (op.container) op.container.append(my.$widget);
			my.$avatar.find('img').attr('src', src);
			my.fillComments(op.fbNode.comments);
			new Facebook.Class.Status({
				$container: my.$status,
				fbNode: op.fbNode
			});
			if (op.fbNode.likes) new Facebook.Class.Likes({
				$container: my.$likes,
				fbNode: op.fbNode.likes
			});
		});
	},
	
	fillComments: function (fbo) {
		if (!fbo) return;
		var my = this, nodes = fbo.data, comments = my.$comments;
		for (var i=0,l=nodes.length; i<l; i++) {
			new Facebook.Class.Comment({
				$container: comments,
				fbNode: nodes[i]
			});
		}
	}
});

Facebook.Class.Comment = new Class({
	
	Extends: Facebook.Class.Base,
	
	pv_options: {
		container: null,
		fbNode: null,
		
		elements: {
			wija: false,
			$widget: {
				css: {
					position: 'relative',
					width: '100%',
					margin: 'auto',
					textAlign: 'left',
					clear: 'both'
				}
			},
			$avatar: {
				tag: '<img/>',
				attr: {
					width: '32',
					height: '32'
				},
				css: {
					width: 24,
					height: 24,
					margin: '0 5px 2px 0',
					padding: 0,
					'float':'left'
				}
			},
			$message: {
				tag: '<p/>',
				css: {
					position: 'relative',
					marginLeft: 32,
					fontSize: '12px',
					fontFamily: 'Georgia'
				},
				build: function (my, op) {
					this.addClass(my.classId(op.fbNode.id));
				//my.indexId(this, op.fbNode.id);
				}
			},
			$likes: {
				tag: '<div class="likes"/>',
				wija: true,
				css: {
					marginLeft: 32,
					backgroundColor: '#CCA'
				}
			}
		}
	},

	initialize: function (options) {
		var my = this, op = my.pv_options;
		jQuery.extend(op, options);
		if (!Facebook.People) Facebook.People = {};
		my.parent();
		my.createWidget(function () {
			var src = 'http://graph.facebook.com/' + op.fbNode.from.id + '/picture';
			my.$message.append('<div><b><a href="">' + op.fbNode.from.name + '</a></b> ' + op.fbNode.message + '</div>');
			if (op.$container) {
				op.$container.empty();
				op.$container.append(my.$widget);
			}
			my.$widget.find('img').attr('src', src);
			if (op.fbNode.likes) new Facebook.Class.Likes({
				$container: my.$likes,
				fbNode: op.fbNode.likes
			});
		});
	}
});

Facebook.Class.Status = new Class({
	
	Extends: Facebook.Class.Base,
	
	pv_options: {
		elements: {
			wija: false,
			buttonCss: {
				cursor: 'pointer'
			},
			disabledCss: {
				color: 'grey'
			},
			$widget: {
				css: {
					position: 'relative',
					color: '#48F',
					padding: '2px 0'
				}
			},
			$time: {
				tag: '<span/>',
				css: 'disabledCss'
			},
			$dot1: {
				tag: '<span style="cursor:default"> . </span>'
			},
			$like: {
				tag: '<span class="like"/>',
				html: 'like',
				css: 'buttonCss'
			},
			$dot2: {
				tag: '<span style="cursor:default"> . </span>'
			},
			$comment: {
				tag: '<span/>',
				wija: true,
				html: 'Comment',
				css: 'disabledCss'
			},
			$dot3: {
				tag: '<span style="cursor:default"> . </span>'
			},
			$remove: {
				tag: '<span/>',
				html: 'Remove',
				css: 'buttonCss'
			},
			build: function (my, op) {
				var node = op.fbNode, iLike = false;
				my.$time.html((new Date(node.created_time)).toString());
			
				if (Facebook.User && Facebook.User.id) {
					var likes = node.likes && node.likes.data;
					if (likes) for (var i=0,l=likes.length; i<l; i++) {
						//my.trace('Like name='+likes[i].name + ', id='+likes[i].id + ', userid=' + Facebook.User.id);
						if (likes[i].id != Facebook.User.id) continue;
						iLike = true;
						break;
					}
				}
				// TODO: Why do we need a setTimeout here???? It works but???
				setTimeout(function () {
					my.$remove.click(function () {
						my.removeItem(node.id);
					});
					if (iLike) {
						my.$like.empty();
						my.$like.html('Unlike');
						my.$like.click(function () {
							my.likeIt(node.id, false);
						});
					}
					else {
						my.$like.html('Like');
						my.$like.click(function () {
							my.likeIt(node.id, true);
						});
					}
				//my.trace('like text='+my.$like.html());
				}, 1);
				if (op.$container) {
					op.$container.empty();
					op.$container.append(my.$widget);
				}
			}
		}
	},

	initialize: function (options) {
		var my = this, op = my.pv_options;
		jQuery.extend(op, options);
		my.parent();
		my.createWidget();
	}
});

Facebook.Class.Likes = new Class({
	
	Extends: Facebook.Class.Base,
	
	pv_options: {
		showSpeed: 0,
		hideSpeed: 0,
		elements: {
			wija: false,
			$widget: {
				wija: false,
				css: {
					position: 'relative',
					padding: '2px 0'
				}
			}
		}
	},

	initialize: function (options) {
		var my = this, op = my.pv_options;
		jQuery.extend(op, options);
		my.parent();
		if (!op.$container) return;
		my.createWidget(function () {
			var ot = '', nodes;
			if (typeof op.fbNode == 'number') {
				ot = op.fbNode + ' people like this';
			}
			else {
				nodes = op.fbNode.data;
				if (nodes && nodes.length) {
					ot += 'Who likes this? ';
					for (var i=0,l=nodes.length; i<l; i++) {
						if (i) ot += ', '
						ot += nodes[i].name;
					}
				}
			}
			op.$container.empty();
			if (ot) {
				my.$widget.html(ot);
				op.$container.append(my.$widget).show();
			}
			else {
				op.$container.hide();
			}
		});
	}
});

Facebook.Class.User = new Class({
	
	Extends: Facebook.Class.Base,
	
	pv_options: {
		elements: {
			wija: false,
			$widget: {
				id: 'userInfo',
				css: {
					position: 'relative',
					width: Facebook.ColumnWidth,
					margin: 'auto',
					textAlign: 'left',
					fontSize: '14px',
					fontFamily: 'Georgia',
					backgroundColor: '#DDD',
					padding: '1px 5px'
				}
			},
			$name: {
				tag: '<div class="name"/>'
			},
			$location: {
				tag: '<div class="location"/>'
			}
		}
	},

	initialize: function (options) {
		var my = this, op = my.pv_options;
		jQuery.extend(op, options);
		if (!Facebook.People) Facebook.People = {};
		my.parent();
		my.createWidget(function () {
			if (op.data.name) my.$name.html(op.data.name);
			if (op.data.location) my.$location.html(op.data.location.name);
			if (op.after) my.$widget.insertAfter(op.after);
		});
	}
});

var ResetFacebook = function () {
	Baja.RemoveSession('FbAccessFresh');
	Baja.RemoveSession('FbAccessToken');
};

var OldFacebook = function () {
	var oldFbAccessToken = "140410776032411|2.k4e3SlzWeDLNg93N77qzkA__.3600.1303545600.1-100002302871103|cXU3PqqFhpRCaRniYnfQOWwfpKw";
	Baja.Session('FbAccessToken', oldFbAccessToken);
};

